home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 January: Mac OS SDK / Dev.CD Jan 99 SDK1.toast / Development Kits / AppleScript / Development Tools / Sample Code / 7Edit 3.1 / Sources / SVAESetData.c < prev    next >
Encoding:
Text File  |  1995-11-20  |  22.1 KB  |  834 lines  |  [TEXT/CWIE]

  1. // SVAESetData.c
  2. //
  3. // 7Edit 3.1d1. Original version by Jon Lansdell and Nigel Humphreys.
  4. // 3.1 updates by Greg Sutton.
  5. // ©Apple Computer Inc 1995, all rights reserved.
  6.  
  7. #include "SVAESetData.h"
  8.  
  9. #include "SVEditWindow.h"
  10. #include "SVEditGlobals.h"
  11. #include "SVEditAEUtils.h"
  12. #include "SVAETextUtils.h"
  13. #include "SVAppleEvents.h"
  14.  
  15. #include "SVAESelect.h"
  16. #include "SVAECreate.h"
  17.  
  18. #include <PLStringFuncs.h>
  19. #include <string.h>
  20.  
  21.  
  22. // --------------------------------------------------------------------------
  23. //    Name:             DoSetData
  24. //    Purpose:        Handles the SetData Apple Event, extracting the direct
  25. //                    object (which says what to set) and the data (what to set
  26. //                    it to).
  27. // --------------------------------------------------------------------------
  28.      
  29. pascal OSErr    DoSetData(const AppleEvent    *theAppleEvent,
  30.                                 AppleEvent    *reply,
  31.                                 long        handlerRefCon)
  32. {
  33. #pragma unused (reply, handlerRefCon)
  34.     
  35.     AEDesc     directObj = {typeNull, NULL},
  36.             dataDesc = {typeNull, NULL};
  37.     OSErr      err;
  38.             
  39.         // pick up the direct object, which is the object whose data is to be set
  40.     err = AEGetParamDesc(theAppleEvent,  keyDirectObject,
  41.                                     typeWildCard, &directObj);
  42.     if (noErr != err) goto done;
  43.         
  44.         // now the data to set it to - typeWildCard means get as is
  45.         // e.g. this is the name of the font for text
  46.     err = AEGetParamDesc(theAppleEvent, keyAEData, typeWildCard, &dataDesc);
  47.     if (noErr != err) goto done;
  48.     
  49.         // missing any parameters?
  50.     err = GotRequiredParams(theAppleEvent);
  51.     if (noErr != err) goto done;
  52.     
  53.         // set the data
  54.     err = HandleSetData(&directObj, &dataDesc);
  55.  
  56. done:            
  57.     if (directObj.dataHandle)
  58.         AEDisposeDesc(&directObj);
  59.     if (dataDesc.dataHandle)
  60.         AEDisposeDesc(&dataDesc);
  61.  
  62.     return(err);
  63. }    // DoSetData
  64.  
  65.  
  66. // ---------------------------------------------------------------------------
  67. //        Name:             HandleSetData
  68. //        Purpose:        Resolves the object into a token (could be one of 
  69. //                        many) andthe sets the data of that object to dataDesc.
  70. // ---------------------------------------------------------------------------
  71.      
  72. OSErr HandleSetData(const AEDesc *theObj, AEDesc *dataDesc)
  73. {
  74.     TextToken       theTextToken;
  75.     Size            tokenSize;
  76.     AEDesc          objTokenDesc = {typeNull, NULL},
  77.                     itemDesc = {typeNull, NULL},
  78.                     ignoreResult = {typeNull, NULL};
  79.     long            index;
  80.     DescType        returnedType;
  81.     OSErr           err;
  82.  
  83.         //    Coerce theObj into a token which we can use - 
  84.         //         set the property or data for that token
  85.     if (typeObjectSpecifier == theObj->descriptorType)
  86.         err = AEResolve(theObj, kAEIDoMinimum, &objTokenDesc);
  87.     else    // Otherwise, just copy it
  88.         err = AEDuplicateDesc(theObj, &objTokenDesc);
  89.  
  90.     if (noErr != err) goto done;
  91.             
  92.     switch (objTokenDesc.descriptorType)
  93.     {
  94.         case typeMyWindowProp:
  95.             err = SetWindowProperty(&objTokenDesc, dataDesc);
  96.             break;
  97.         
  98.         case typeMyTextProp:
  99.             err = SetTextProperty(&objTokenDesc, dataDesc);
  100.             break;
  101.             
  102.         case typeMyText:
  103.             GetRawDataFromDescriptor(&objTokenDesc,  (Ptr)&theTextToken,
  104.                                             sizeof(theTextToken), &tokenSize);
  105.             
  106.                         // itemDesc is a null descriptor here
  107.             err = CreateAtTextToken(cText, dataDesc, &theTextToken,
  108.                                                     &itemDesc, &ignoreResult);
  109.             break;
  110.  
  111.         case typeAEList:                // If it's a list then do each item
  112.             err = AECountItems(&objTokenDesc, &index);
  113.             if (noErr != err) goto done;
  114.  
  115.             for (; index > 0; index--)
  116.             {
  117.                 err = AEGetNthDesc(&objTokenDesc, index, typeWildCard, &returnedType, &itemDesc);
  118.  
  119.                 if (noErr == err)        // Get property by calling this function again
  120.                     err = HandleSetData(&itemDesc, dataDesc);
  121.                 
  122.                 if (itemDesc.dataHandle)
  123.                     AEDisposeDesc(&itemDesc);
  124.             }
  125.             break;
  126.             
  127.         default:
  128.             err = errAEWrongDataType;
  129.     }
  130.  
  131. done:
  132.     if (objTokenDesc.dataHandle)    
  133.         AEDisposeDesc(&objTokenDesc);
  134.     if (itemDesc.dataHandle)    
  135.         AEDisposeDesc(&itemDesc);
  136.     if (ignoreResult.dataHandle)
  137.         AEDisposeDesc(&ignoreResult);
  138.  
  139.     return(err);
  140. } // HandleSetData
  141.  
  142.  
  143. OSErr    SetWindowSelectionProperty(WindowPtr theWindow, const AEDesc *dataDesc)
  144. {
  145.     AEDesc        textDesc = {typeNull, NULL},
  146.                 ignoreResult = {typeNull, NULL};
  147.     TextToken    aTextToken;
  148.     Size        actualSize;
  149.     short        ignore;
  150.     OSErr        err;
  151.         
  152.     // first check to see if we are dealing with a TEXT descriptor or
  153.     // an object specifier. Since AECoerceDesc will end up calling
  154.     // AEResolve, we don't want to call this if the user entered something
  155.     // like 'Set selection of window 1 to "some text '
  156.  
  157.     switch (dataDesc->descriptorType)
  158.     {
  159.         case typeChar:
  160.         case typeIntlText:
  161.         case typeStyledText:
  162.             err = GetWindowSelection(theWindow, &aTextToken, &ignore);
  163.             if (noErr != err) goto done;
  164.  
  165.                         // textDesc is a null descriptor here
  166.             err = CreateAtTextToken(cText, dataDesc, &aTextToken,
  167.                                                     &textDesc, &ignoreResult);
  168.             break;
  169.             
  170.         default:     // we are dealing with an object specifier
  171.             err = AECoerceDesc(dataDesc, typeMyText, &textDesc);
  172.             if (noErr != err) goto done;
  173.             
  174.             GetRawDataFromDescriptor(&textDesc, (Ptr)&aTextToken, sizeof(aTextToken),
  175.                                             &actualSize);
  176.                                             
  177.             SelectTextToken(&aTextToken);
  178.     }
  179.  
  180. done:
  181.     if (textDesc.dataHandle)
  182.         AEDisposeDesc(&textDesc);
  183.  
  184.     return(err);
  185. }
  186.  
  187.  
  188. // ------------------------------------------------------------------------
  189. //    Name:         SetWindowProperty
  190. //    Purpose:    Sets the window property specified in theWindowPropToken to
  191. //                be that supplied in dataDesc.
  192. // ------------------------------------------------------------------------
  193.      
  194. OSErr    SetWindowProperty(const AEDesc *theWPTokenDesc, const AEDesc *dataDesc)
  195. {
  196.     Str255          theNewName;
  197.     DPtr            theDocument;
  198.     Rect            thePosnRect;
  199.     Boolean         theBoolean;
  200.     GrafPtr         oldPort;
  201.     Point           thePosn;
  202.     THPrint         theTHPrint;
  203.     WindowPropToken theWindowPropToken;
  204.     TextToken        aTextToken;
  205.     AEDesc          aDesc = {typeNull, NULL},
  206.                     nullDesc = {typeNull, NULL},
  207.                     ignoreResult = {typeNull, NULL};
  208.     Size            tokenSize;
  209.     short           hOffset;
  210.     short           vOffset;
  211.     AEDesc          resultDesc;
  212.     Handle          hGXJobData;
  213.     OSErr           err;
  214.  
  215.     GetPort(&oldPort);
  216.  
  217.     err = AECoerceDesc(theWPTokenDesc, typeMyWindowProp, &aDesc);
  218.     if (noErr != err) goto done;
  219.  
  220.     GetRawDataFromDescriptor(&aDesc, (Ptr)&theWindowPropToken,
  221.                                     sizeof(theWindowPropToken), &tokenSize);
  222.  
  223.     SetPort(theWindowPropToken.tokenWindowToken.tokenWindow);
  224.     
  225.     theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken.tokenWindow);
  226.     
  227.     switch (theWindowPropToken.tokenProperty)
  228.     {
  229.         case pName:
  230.             err = GetPStringFromDescriptor(dataDesc, theNewName);
  231.             if (noErr != err) goto done;
  232.  
  233.             if (theNewName[0] == 0) 
  234.                 err = errAEWrongDataType;
  235.             else
  236.             {
  237.                 SetWTitle(theWindowPropToken.tokenWindowToken.tokenWindow, theNewName);
  238.                 PLstrcpy(theDocument->theFileName, theNewName); // Should we do this???
  239.                 theDocument->dirty = true;
  240.             }
  241.             break;
  242.             
  243.         case pText:
  244.         case pContents:
  245.                             // Get whole window as place to insert data
  246.             err = TextTokenFromWindowToken(&(theWindowPropToken.tokenWindowToken), &aTextToken);
  247.             if (noErr != err) goto done;
  248.  
  249.             err = CreateAtTextToken(cText, dataDesc, &aTextToken,
  250.                                                     &nullDesc, &ignoreResult);
  251.             break;
  252.             
  253.         case pBounds:
  254.             err = GetRectFromDescriptor(dataDesc, &thePosnRect);
  255.             // the rectangle is for the structure region, and is in global coordinates
  256.             // MoveWindow and SizeWindow apply to the content region, so we have to massage a little
  257.  
  258.             thePosnRect.top    += (**((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->contRgn).rgnBBox.top -
  259.                                   (**((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->strucRgn).rgnBBox.top;
  260.                                                         
  261.             thePosnRect.left   += (**((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->contRgn).rgnBBox.left -
  262.                                   (**((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->strucRgn).rgnBBox.left;
  263.                                                         
  264.             thePosnRect.bottom += (**((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->contRgn).rgnBBox.bottom -
  265.                                   (**((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->strucRgn).rgnBBox.bottom;
  266.                                                         
  267.             thePosnRect.right  += (**((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->contRgn).rgnBBox.right -
  268.                                   (**((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->strucRgn).rgnBBox.right;
  269.             
  270.             if (EmptyRect(&thePosnRect)) 
  271.                 err = errAECorruptData;
  272.             else
  273.             {
  274.                 MoveWindow(theWindowPropToken.tokenWindowToken.tokenWindow,
  275.                                      thePosnRect.left,
  276.                                      thePosnRect.top,
  277.                                      false);
  278.                 SizeWindow(theWindowPropToken.tokenWindowToken.tokenWindow,
  279.                                      thePosnRect.right- thePosnRect.left,
  280.                                      thePosnRect.bottom-thePosnRect.top,
  281.                                      true);
  282.                 ResizeWindow(theDocument);
  283.             }
  284.             break;
  285.             
  286.         case pPosition:
  287.             err = GetPointFromDescriptor(dataDesc, &thePosn);
  288.             // the point is for the structure region, and is in global coordinates
  289.             // MoveWindow applies to the content region, so we have to massage a little
  290.     
  291.             hOffset = (**((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->contRgn).rgnBBox.left -
  292.                       (**((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->strucRgn).rgnBBox.left;
  293.                                 
  294.             vOffset = (**((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->contRgn).rgnBBox.top -
  295.                       (**((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->strucRgn).rgnBBox.top;
  296.                                 
  297.                                 
  298.             thePosn.v  += vOffset;
  299.             thePosn.h  += hOffset;
  300.             
  301.             MoveWindow(theWindowPropToken.tokenWindowToken.tokenWindow,
  302.                                  thePosn.h,
  303.                                  thePosn.v,
  304.                                  false);
  305.                                  
  306.             ResizeWindow(theDocument);
  307.             break;
  308.             
  309.         case pIsZoomed:
  310.             err = GetBooleanFromDescriptor(dataDesc, &theBoolean);
  311.             if (theBoolean)
  312.                 ZoomWindow(qd.thePort, inZoomOut, false);
  313.             else
  314.                 ZoomWindow(qd.thePort, inZoomIn, false);
  315.                                                      
  316.             ResizeWindow(theDocument);
  317.             break;
  318.             
  319.         case pVisible:
  320.             err = GetBooleanFromDescriptor(dataDesc, &theBoolean);
  321.             if (theBoolean)
  322.                 ShowWindow(theWindowPropToken.tokenWindowToken.tokenWindow);
  323.             else
  324.                 HideWindow(theWindowPropToken.tokenWindowToken.tokenWindow);
  325.             break;
  326.             
  327.         case pPageSetup:
  328.             if (! gGXIsPresent)
  329.             {
  330.                 err = GetTHPrintFromDescriptor(dataDesc, &theTHPrint);
  331.                     
  332.                 if (theTHPrint) 
  333.                 {
  334.                     if (theDocument->thePrintSetup) 
  335.                         DisposHandle((Handle)theDocument->thePrintSetup);
  336.                         
  337.                     theDocument->thePrintSetup = theTHPrint;
  338.                     
  339.                     ResizePageSetupForDocument(theDocument);
  340.                 }
  341.             }
  342.             else
  343.                 err = errAEEventNotHandled;                     
  344.             break;
  345.             
  346.         case pGXPageSetup:
  347.             if (gGXIsPresent)
  348.             {
  349.                 err = AECoerceDesc(dataDesc,typeTGXPrint,&resultDesc);
  350.     
  351.                 hGXJobData = nil;
  352.     
  353.                 if (err==noErr) 
  354.                 {
  355.                     hGXJobData = NewHandle(GetHandleSize(resultDesc.dataHandle));
  356.     
  357.                     BlockMove(*(resultDesc.dataHandle),
  358.                                         *hGXJobData,
  359.                                         GetHandleSize(resultDesc.dataHandle));
  360.                 }
  361.     
  362.                 if (resultDesc.dataHandle) 
  363.                     AEDisposeDesc(&resultDesc);
  364.                     
  365.                 if (hGXJobData) 
  366.                 {
  367.                         
  368.                     GXUnflattenJobFromHdl(theDocument->documentJob, hGXJobData);
  369.                     err = GXGetJobError(theDocument->documentJob);
  370.                     
  371.                     ResizePageSetupForDocument(theDocument);
  372.                 }
  373.             }
  374.             else
  375.                 err = errAEEventNotHandled;                     
  376.             break;
  377.             
  378.         case pSelection:
  379.             err = SetWindowSelectionProperty(theWindowPropToken.tokenWindowToken.tokenWindow, dataDesc);
  380.             break;
  381.     
  382.         default:    
  383.             err = errAEEventNotHandled;
  384.     }
  385.     
  386. done:
  387.     if (aDesc.dataHandle)    
  388.         AEDisposeDesc(&aDesc);
  389.     if (nullDesc.dataHandle)        // You'd hope not
  390.         AEDisposeDesc(&nullDesc);
  391.     if (ignoreResult.dataHandle)    
  392.         AEDisposeDesc(&ignoreResult);
  393.  
  394.     SetPort(oldPort);
  395.     
  396.     return(err);
  397. } // SetWindowProperty
  398.  
  399.  
  400.  
  401. OSErr    GetTHPrintFromDescriptor(const AEDesc *sourceDesc, THPrint *result)
  402. {
  403.     Size    ptSize;
  404.     AEDesc  resultDesc;
  405.     OSErr   err;
  406.     
  407.     *result = NULL;
  408.     
  409.     err = AECoerceDesc(sourceDesc, typeTPrint, &resultDesc);
  410.     if (noErr != err) goto done;
  411.     
  412.     *result = (THPrint)NewHandle(sizeof(TPrint));
  413.     
  414.     PrOpen();
  415.     PrintDefault(*result);
  416.     
  417.     HLock((Handle)*result);
  418.     GetRawDataFromDescriptor(&resultDesc, (Ptr)**result, sizeof(TPrint), &ptSize);
  419.     HUnlock((Handle)*result);
  420.     
  421.     if ((ptSize<sizeof(TPrint)) || (PrValidate(*result)))
  422.     {
  423.         err = errAECoercionFail;
  424.         DisposHandle((Handle)*result);
  425.         *result = NULL;
  426.     }
  427.     
  428.     PrClose();
  429.  
  430. done:    
  431.     if (resultDesc.dataHandle) 
  432.         AEDisposeDesc(&resultDesc);
  433.         
  434.     return(err);
  435. } // GetTHPrintFromDescriptor
  436.  
  437.  
  438.  
  439. // ----------------------------------------------------------------------
  440. //    Name:         SetTextProperty
  441. //    Purpose:    Sets the text property specfied by theTextPropToken to
  442. //                that in dataDesc.
  443. // ----------------------------------------------------------------------
  444.      
  445. OSErr    SetTextProperty(const AEDesc *tokenDesc, const AEDesc *dataDesc)
  446. {
  447.     DPtr              theDoc;
  448.     Str255            name;
  449.     short             theSize;
  450.     Style             onStyle;
  451.     Style             offStyle;
  452.     TextPropToken     theTextPropToken;
  453.     AEDesc            newDesc = {typeNull, NULL},
  454.                     nullDesc = {typeNull, NULL},
  455.                     ignoreResult = {typeNull, NULL};
  456.     Size              tokenSize;
  457.     OSErr             err;
  458.     
  459.       err = AECoerceDesc(tokenDesc, typeMyTextProp, &newDesc);
  460.       if (noErr != err) goto done;
  461.  
  462.     GetRawDataFromDescriptor(&newDesc, (Ptr)&theTextPropToken,
  463.                                     sizeof(theTextPropToken), &tokenSize);
  464.         
  465.     theDoc = DPtrFromWindowPtr(theTextPropToken.tokenTextToken.tokenWindow);
  466.     theDoc->dirty = true;
  467.     
  468.     switch (theTextPropToken.tokenProperty)
  469.     {
  470.         case pText:
  471.         case pContents:
  472.             err = CreateAtTextToken(cText, dataDesc, &(theTextPropToken.tokenTextToken),
  473.                                                                 &nullDesc, &ignoreResult);
  474.             break;
  475.             
  476.         case pFont:
  477.             err = GetPStringFromDescriptor(dataDesc, name);
  478.             if (noErr != err) goto done;
  479.             err = SetFontOfTextToken(&theTextPropToken.tokenTextToken, name);
  480.             break;
  481.             
  482.         case pPointSize:    
  483.             err = GetIntegerFromDescriptor(dataDesc, &theSize);
  484.             if (noErr != err) goto done;
  485.             err = SetSizeOfTextToken(&theTextPropToken.tokenTextToken, theSize);
  486.             break;
  487.             
  488.         case pTextStyles:
  489.             onStyle  = 0;
  490.             offStyle = 0;
  491.             
  492.             err = GetTextStyles(dataDesc, &onStyle, &offStyle);
  493.             if (noErr != err) goto done;
  494.  
  495.             if (onStyle & offStyle != 0)
  496.                 err = errAEEventFailed;
  497.             else
  498.                 err = SetStyleOfTextToken(&theTextPropToken.tokenTextToken, onStyle, offStyle);
  499.             break;
  500.         
  501.         default:
  502.             err = errAEWrongDataType;
  503.     }
  504.  
  505. done:
  506.     if (newDesc.dataHandle)
  507.         AEDisposeDesc(&newDesc);
  508.             
  509.     return(err);
  510. } // SetTextProperty
  511.  
  512.     
  513. short ItemForNamedFont(Str255 theName)
  514. {
  515.     Str255  itemName;
  516.     short   limit;
  517.  
  518.     limit = CountMItems(myMenus[fontM]);
  519.     while (limit>0)
  520.     {
  521.         GetItem(myMenus[fontM],limit, itemName);
  522.         if (IUEqualString(theName, itemName)==0) 
  523.             return(limit);
  524.         else
  525.             limit--;
  526.     }
  527.     return(0);
  528. } // ItemForNamedFont
  529.  
  530.  
  531. // -----------------------------------------------------------------------
  532. //    Name:         SetFontOfTextToken
  533. //    Purpose:    Sets the font of the text specified by theToken to 
  534. //                the font in name.
  535. // -----------------------------------------------------------------------
  536.      
  537. OSErr    SetFontOfTextToken(TextToken* theToken, Str255 name)
  538. {
  539.     DPtr        docPtr;
  540.     TextToken    oldSelection;
  541.     short        theNumber,
  542.                 theItem;
  543.     TextStyle    newStyle;
  544.     Boolean        fCurrentSelection;
  545.     OSErr        err;
  546.  
  547.     docPtr = DPtrFromWindowPtr(theToken->tokenWindow);
  548.     
  549.     if (!docPtr) return(errAENoSuchObject);
  550.         
  551.                 // ignore theNumber result
  552.     err = GetWindowSelection(theToken->tokenWindow, &oldSelection, &theNumber);
  553.     if (noErr != err) goto done;
  554.     
  555.     if (memcmp(theToken, &oldSelection, sizeof(TextToken)))
  556.     {
  557.         fCurrentSelection = false;
  558.         err = SelectTextToken(theToken);    // Only set the selection if it's different
  559.         if (noErr != err) goto done;
  560.     }
  561.     else
  562.         fCurrentSelection = true;
  563.             
  564.     GetFNum(name, &theNumber);
  565.     
  566.     theItem = ItemForNamedFont(name); // returns 0 if failed - i.e. SystemFont
  567.     
  568.     if (gFontMItem)
  569.         CheckItem(myMenus[fontM], gFontMItem, false);
  570.     
  571.     gFontMItem = theItem;
  572.     CheckItem(myMenus[fontM], gFontMItem, true);
  573.     
  574.     docPtr->theFont = theNumber;
  575.         
  576.     newStyle.tsFont = theNumber;
  577.     TESetStyle(doFont, &newStyle, true, docPtr->theText); 
  578.     
  579.     AdjustScrollbars(docPtr, false);
  580.     DrawPageExtras(docPtr);
  581.     docPtr->dirty = true;
  582.     
  583.     if (! fCurrentSelection)
  584.         err = SelectTextToken(&oldSelection);
  585.  
  586. done:    
  587.     return(err);
  588. } // SetFontOfTextToken
  589.     
  590. // -----------------------------------------------------------------------
  591. //    Name:             SetSizeOfTextToken
  592. //    Purpose:        Sets the size of the text specified by theToken to 
  593. //                    the size in theSize.
  594. // -----------------------------------------------------------------------
  595.      
  596. OSErr    SetSizeOfTextToken(TextToken* theToken, short theSize)
  597. {
  598.     DPtr        docPtr;
  599.     TextToken    oldSelection;
  600.     TextStyle    newStyle;
  601.     short        ignore;
  602.     Boolean        fCurrentSelection;
  603.     OSErr        err;
  604.  
  605.     docPtr = DPtrFromWindowPtr(theToken->tokenWindow);
  606.     
  607.     if (!docPtr) return(errAENoSuchObject);
  608.         
  609.                 // Save the old selection
  610.     err = GetWindowSelection(theToken->tokenWindow, &oldSelection, &ignore);
  611.     if (noErr != err) goto done;
  612.     
  613.     if (memcmp(theToken, &oldSelection, sizeof(TextToken)))
  614.     {
  615.         fCurrentSelection = false;
  616.         err = SelectTextToken(theToken);
  617.         if (noErr != err) goto done;
  618.     }
  619.     else
  620.         fCurrentSelection = true;
  621.                             
  622.     docPtr->theSize = theSize;
  623.     
  624.     newStyle.tsSize = theSize;
  625.     TESetStyle(doSize, &newStyle, true, docPtr->theText); 
  626.     
  627.     AdjustScrollbars(docPtr, false);
  628.     DrawPageExtras(docPtr);
  629.     docPtr->dirty = true;
  630.     
  631.     if (! fCurrentSelection)    // If we reset the selection we may loose the
  632.         err = SelectTextToken(&oldSelection);    // Size or style just set
  633.  
  634. done:    
  635.     return(err);
  636. } // SetSizeOfTextToken
  637.     
  638. // ------------------------------------------------------------------------
  639. //    Name:             SetStyleOfTextToken
  640. //    Purpose:        Sets the style of the text specified by theToken to 
  641. //                    the style in theStyle.
  642. // ------------------------------------------------------------------------
  643.      
  644. OSErr    SetStyleOfTextToken(TextToken* theToken, Style onStyle, Style offStyle)
  645. {
  646.     DPtr        docPtr;
  647.     TextToken    oldSelection;
  648.     TextStyle    newStyle;
  649.     short        mode;
  650.     Boolean        wasContinuous;
  651.     short        ignore;
  652.     Boolean        fCurrentSelection;
  653.     OSErr        err;
  654.  
  655.     docPtr = DPtrFromWindowPtr(theToken->tokenWindow);
  656.     
  657.     if (!docPtr) return(errAENoSuchObject);
  658.         
  659.                 // Save the old selection
  660.     err = GetWindowSelection(theToken->tokenWindow, &oldSelection, &ignore);
  661.     if (noErr != err) goto done;
  662.     
  663.     if (memcmp(theToken, &oldSelection, sizeof(TextToken)))
  664.     {
  665.         fCurrentSelection = false;
  666.         err = SelectTextToken(theToken);
  667.         if (noErr != err) goto done;
  668.     }
  669.     else
  670.         fCurrentSelection = true;
  671.                             
  672.     docPtr->theStyle = onStyle;
  673.     
  674.         // Check to see if off styles are on for whole selection
  675.     mode = doFace;
  676.     
  677.     wasContinuous = TEContinuousStyle(&mode, &newStyle, docPtr->theText);
  678.     if ((newStyle.tsFace & offStyle) != offStyle) // not off styles are on for all
  679.     {
  680.             // switch on across board so that toggle off will clear all
  681.         newStyle.tsFace  = offStyle - (newStyle.tsFace & offStyle);
  682.         TESetStyle(doFace+doToggle, &newStyle, false, docPtr->theText); 
  683.     }
  684.         
  685.     newStyle.tsFace  = offStyle;
  686.     TESetStyle(doFace+doToggle, &newStyle,(onStyle==0), docPtr->theText); // toggle all to off
  687.     
  688.     mode = doFace;
  689.     if (onStyle)
  690.     {
  691.         wasContinuous = TEContinuousStyle(&mode, &newStyle, docPtr->theText);
  692.         if ((newStyle.tsFace & onStyle) != onStyle) // are they on for only a few chars
  693.         { 
  694.                 // Need to make all chars have these characteristics
  695.             newStyle.tsFace = onStyle - (newStyle.tsFace & onStyle); // take out those continuous
  696.             TESetStyle(doFace+doToggle, &newStyle, true, docPtr->theText);
  697.         }
  698.         else
  699.             TESetStyle(0, &newStyle, true, docPtr->theText); // Just Draw it, no changes
  700.     }
  701.         
  702.     AdjustScrollbars(docPtr, false);
  703.     DrawPageExtras(docPtr);
  704.     docPtr->dirty = true;
  705.     
  706.     if (! fCurrentSelection)
  707.         err = SelectTextToken(&oldSelection);
  708.  
  709. done:    
  710.     return(err);
  711. } // SetStyleOfTextToken
  712.  
  713.     
  714. OSErr    GetTextStyles(const AEDesc *dataDesc, Style *onStyles, Style *offStyles)
  715. {
  716.     OSErr      myErr;
  717.     OSErr      ignoreErr;
  718.     AEDescList textSDesc;
  719.     AEDescList onDesc;
  720.     AEDescList offDesc;
  721.     Boolean    hadPlain;
  722.         
  723.   textSDesc.dataHandle = nil;
  724.   onDesc.dataHandle    = nil;
  725.   offDesc.dataHandle   = nil;
  726.     
  727.     *onStyles  = 0;
  728.     *offStyles = 0;
  729.     
  730.   myErr = AECoerceDesc(dataDesc, typeAERecord, &textSDesc);
  731.     
  732.     if (myErr==noErr)
  733.       myErr = AEGetKeyDesc(&textSDesc, keyAEOnStyles, typeAEList, &onDesc);
  734.     
  735.     if (myErr==noErr)
  736.       myErr = AEGetKeyDesc(&textSDesc, keyAEOffStyles, typeAEList, &offDesc);
  737.     
  738.     if (myErr==noErr)
  739.         myErr = MakeStyleFromAEList(&onDesc,  onStyles, &hadPlain);
  740.     
  741.     if (hadPlain)
  742.         *offStyles = bold+italic+underline+outline+shadow+condense+extend;
  743.     else
  744.         {
  745.             if (myErr==noErr)
  746.                 myErr = MakeStyleFromAEList(&offDesc, offStyles, &hadPlain);
  747.             
  748.             if (hadPlain)
  749.                 myErr = errAEEventFailed;
  750.         }
  751.         
  752.     if (textSDesc.dataHandle)
  753.         ignoreErr = AEDisposeDesc(&textSDesc);
  754.         
  755.     if (onDesc.dataHandle)
  756.         ignoreErr = AEDisposeDesc(&onDesc);
  757.         
  758.     if (offDesc.dataHandle)
  759.         ignoreErr = AEDisposeDesc(&offDesc);
  760.     
  761.     return(myErr);
  762. } // GetTextStyles
  763.  
  764. // -----------------------------------------------------------------------
  765. //    Name:         AddDescStyleItem
  766. //    Purpose:    Adds the kAEXXXX style to theStyle.
  767. // -----------------------------------------------------------------------
  768.      
  769. void    AddDescStyleItem(DescType theDesc, Style *theStyle)
  770. {
  771.     if (theDesc == kAEBold)
  772.         *theStyle = *theStyle+bold;
  773.     else
  774.     if (theDesc == kAEItalic)
  775.         *theStyle = *theStyle+italic;
  776.     else
  777.     if (theDesc == kAEUnderline)
  778.         *theStyle = *theStyle+underline;
  779.     else
  780.     if (theDesc == kAEOutline)
  781.         *theStyle = *theStyle+outline;
  782.     else
  783.     if (theDesc == kAEShadow)
  784.         *theStyle = *theStyle+shadow;
  785.     else
  786.     if (theDesc == kAECondensed)
  787.         *theStyle = *theStyle+condense;
  788.     else
  789.     if (theDesc == kAEExpanded)
  790.         *theStyle = *theStyle+extend;
  791.     else
  792.     if (theDesc == kAEPlain)
  793.         *theStyle = 0;
  794. } // AddDescStyleItem
  795.     
  796. OSErr    MakeStyleFromAEList(const AEDescList *styleList, Style *theStyle, Boolean *hadPlain)
  797. {
  798.     OSErr     myErr;
  799.     DescType  styleDesc;
  800.     long      itemsInList;
  801.     long      actSize;
  802.     AEKeyword keywd;
  803.     DescType  typeCode;
  804.         
  805.     *hadPlain = false;
  806.     *theStyle = 0;
  807.     
  808.   myErr = AECountItems(styleList, &itemsInList);
  809.     while (itemsInList>0)
  810.       if (myErr==noErr)
  811.             {
  812.                 myErr  = AEGetNthPtr(styleList,
  813.                                                          itemsInList,
  814.                                                          typeEnumerated,
  815.                                                          &keywd,
  816.                                                          &typeCode,
  817.                                                          (Ptr)&styleDesc,
  818.                                                          sizeof(styleDesc),
  819.                                                          &actSize);
  820.                 
  821.                 AddDescStyleItem(styleDesc, theStyle);
  822.                 
  823.                 if (styleDesc == kAEPlain) 
  824.                   {
  825.                         itemsInList = 0;
  826.                         *hadPlain    = true;
  827.                     }
  828.                 else
  829.                   itemsInList--;
  830.             }
  831.             
  832.     return(myErr);
  833. } // MakeStyleFromAEList
  834.